
/*---------------------------------------------------------------------------

  FILENAME:
        server.c

  PURPOSE:
	transport multi sockets command to serial port, 
	and deliver datas back to diffirrent sockets, 
	the main entry.

  REVISION HISTORY:
        Date            Engineer        Revision        Remarks
	16/02/2009	Vincent. Young	1.2	

  NOTES:


  LICENSE:
        Copyright (c) 2009, Vincent Young (vincentgodyoung@hotmail.com)

        This source code is released for free distribution under the terms
        of the GNU General Public License.

----------------------------------------------------------------------------*/

// local project include files
#include "serial.h"
#include "socket.h"
#include "sock2serial.h"
#include "serial2sock.h"
#include "cmdbufqueue.h"

// system library include files
#include <errno.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>

#define LOGREGMODE FALSE

int linstening(int serverfd)
{
	char addr[128];		// allow max addr length 128
	int retcode;
	pthread_t th_sock2buf;
	int * clientpointer;
	
	while(1)	//监听连接请求
	{		//这里需要保护clientfd对象截堵内存泄漏
		clientpointer = malloc(sizeof(int));
		retcode = TCPServerWaitConnection(serverfd, clientpointer, addr);	//阻塞在此
		if (retcode < 0)
		{
			printf("linstening: wait conection faild [%d]\n", retcode);
			return -1;
		}
#if LOGREGMODE
		printf("linstening: client connected [%d] [%s]\n", *clientpointer, addr);
#endif
		// 每收到一个请求创建一个线程处理
		retcode = pthread_create(&th_sock2buf, NULL, sock2buf, (void *)clientpointer);
		if (retcode != 0) 
			printf("linstening: create sock2buf failed [%d] [%s]\n", retcode, strerror(errno));
#if LOGREGMODE
		printf("linstening: create sock2buf succeeded [%d]\n", retcode);
#endif
		//监视另2个线程是否异常退出，buf2serial, serial2sock，也退出
		//blabla;
	}
	return 0;
}


// 参数说明：
// transport /dev/ttyUSB0 19200 4001
// 开第一个串口，波特率19200，在网络端口4001上开服务，此也是默认参数，可省略
int main(int argc, char* argv[])
{
	//int i, j;
	//int port= PORT1;
	int speed= 19200;
	int sopo = 4001;
	int serverfd;
	int retcode;
	pthread_t th_serial2sock, th_buf2serial;
	
	// 参数处理
	if( argc >= 2)
	if( argc >= 3)
		speed= atoi( argv[ 2]);
	if( argc >= 4)
		sopo = atoi( argv[3] );
	if( argc >= 5)
	{
		printf("rtfm!\n");
		return -5;
	}
	
	// 按配置打开串口网口
#if LOGREGMODE
	printf("Open port[%s], speed= [%dbaud]\n", argv[1], speed);
#endif
	retcode = SerialOpen(argv[1], speed);
	if (retcode < 0)
	{
		printf("Open port[%s] failed! [%d]\n", argv[1], retcode);
		return -3;
	}

#if LOGREGMODE
	printf("Open server listenning socket [%d]\n", sopo);
#endif
	retcode = TCPServerInit( sopo, &serverfd);
	if (retcode < 0)
	{
		printf("tcp server init failed!\n");
		return -2;
	}

	//创建空的初始命令队列
	firstcmd = NULL;
	lastcmd = NULL;
	cmdsum = 0;
	
	// 打开命令缓冲队列到串口的线程
	retcode = pthread_create(&th_buf2serial, NULL, buf2serial, NULL);
	if (retcode != 0)
	{
		printf("create buf2serial failed [%d], [%s]\n", retcode, strerror(errno));
		return -3;
	}
#if LOGREGMODE
	printf("create buf2serial succeeded [%d]\n", retcode);
#endif
	// 打开串口到网口线程
	retcode = pthread_create(&th_serial2sock, NULL, serial2sock, NULL);
	if (retcode != 0) 
	{
		printf("create serial2sock failed [%d], [%s]\n", retcode, strerror(errno));
		return -4;
	}
#if LOGREGMODE
		printf("create serial2sock succeeded [%d]\n", retcode);
#endif	
	// 监听socket，收到连接请求就创建网口到串口线程
	retcode = linstening(serverfd);
	if (retcode < 0)
	{
		printf("you decided it is all too much!\n");
	}
	
	// 异常退出
	printf("close all impossible\n");
	// close all handle, in some other where
	printf("byebye\n");
	return 0;
}

